package com.yf1706.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.yf1706.bean.Function;
import com.yf1706.bean.FunctionType;
import com.yf1706.bean.Role;
import com.yf1706.bean.User;
import com.yf1706.dao.jpa.IFunctionJDAO;
import com.yf1706.dao.jpa.IFunctionTypeJDAO;
import com.yf1706.dao.jpa.IRoleJDAO;
import com.yf1706.dao.jpa.IUserJDAO;
import com.yf1706.vo.FunctionExVO;
import com.yf1706.vo.FunctionTypeExVo;
import com.yf1706.vo.UserEmpRoleVO;

@Service
@Transactional(rollbackFor = Exception.class)
public class GrantService {
	public static final Integer LOGIN_ID = 1;
	@Autowired
	private IUserJDAO ujdao;
	@Autowired
	private IRoleJDAO rjdao;
	@Autowired
	private IFunctionJDAO fjdao;
	@Autowired
	private IFunctionTypeJDAO ftjdao;

	/**
	 * 查询所有角色
	 * @return
	 */
	public List<Role> getAllRoles(){
		return (List<Role>) rjdao.findAll();
	}
	
	/**
	 * 添加新角色
	 * @param roleName
	 */
	public void addNewRole(String roleName){
		try {
			Role role = new Role();
			role.setRoleName(roleName);
			rjdao.save(role);
		} catch (Exception e) {
			e.printStackTrace();
			
		}
	}
	
	/**
	 * 编辑角色
	 * @param roleName
	 */
	public boolean updateRole(int roleId,String roleName) {
		try {
			Role role=rjdao.findByRoleId(roleId);
			role.setRoleName(roleName);
			rjdao.save(role);
			return true;
		}catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			return false;
		}
	}
	
	/**
	 * 删除角色
	 * @param roleId
	 */
	public void deleteRole(int roleId){
		try {
			 Role role=rjdao.findByRoleId(roleId);
			 List<User> users=role.getUsers();
			   if(!users.isEmpty()) {
				   for(User u : users) {
					  if(u.getRoles()!=null) {
						  u.getRoles().remove(role);
					  }
				   }
			   }
			   rjdao.delete(role);
		} catch (Exception e) {
			e.printStackTrace();
			
		}
	}
	
	/**
	 * 返回功能列表，并给当前角色拥有的功能设置选择状态
	 * @param roleId 角色id
	 * @return
	 */
	public List<FunctionTypeExVo> getFunctionTypeExs(int roleId){
		List<FunctionTypeExVo> funcTypeList = new ArrayList<FunctionTypeExVo>();
		//获取所有的分类
		List<FunctionType> types = (List<FunctionType>) ftjdao.findAll();
		//循环分类，找出每个分类下所有的功能（权限）
		if(types != null){
			for(FunctionType type: types){
				FunctionTypeExVo functionTypeExVo = new FunctionTypeExVo();
				functionTypeExVo.setFtId(type.getFtId());
				functionTypeExVo.setFtName(type.getFtName());
				//获取当前分类下的功能权限列表
				List<Object[]> objsList = ftjdao.findFunctionsByRoleId(roleId, type.getFtId());
				//将Object[]转换成FunctionExVo类型
				List<FunctionExVO> funsList = new ArrayList<FunctionExVO>();
				if(objsList != null){
					for(Object[] objs: objsList){
						FunctionExVO functionExVo = new FunctionExVO();
						//权限ID
						functionExVo.setFunId((Integer)objs[0]);
						//权限名
						functionExVo.setFunName((String)objs[2]);
						//权限是否被选中
						functionExVo.setSelected(Integer.parseInt(objs[3].toString())==1);
					    // 添加一条权限记录
						funsList.add(functionExVo);
					}
					//将权限添加到当前分类（成为树的子节点）
					functionTypeExVo.setFunctions(funsList);
				}
				//添加一个分类
				funcTypeList.add(functionTypeExVo);
			}
		}
		return funcTypeList;
	}
	
	/**
	 * 返回用户列表，并给当前用户拥有的角色设置选择状态
	 * @param roleId 角色id
	 * @return
	 */
	public List<UserEmpRoleVO> findUserEmpRoleVO(int roleId){
		List<UserEmpRoleVO> uerl = new ArrayList<UserEmpRoleVO>();
		//获取用户角色视图
		List<Object[]> objs=ujdao.findUserEmpRoleByRoleId(roleId);
		if(objs != null) {
			for(Object[] obj:objs) {
				UserEmpRoleVO uer=new UserEmpRoleVO();
				uer.setUserId((Integer)obj[0]);
				uer.setEmpName((String)obj[1]);
				uer.setIfSelect(Integer.parseInt(obj[2].toString())==1);
				
				uerl.add(uer);
			}
		}
		return uerl;
	}
	
	/**
	 * 给指定的角色授权
	 * @param roleId
	 * @param funcIds
	 */
	public void grantRole(int roleId, List<Integer> funcIds){
		try {
			//获取当前角色
			Role role = rjdao.findByRoleId(roleId);
			if(role.getFunctions() == null){
				role.setFunctions(new ArrayList<Function>());
			}
			//清除当前角色下所有的权限
			role.getFunctions().clear();
			if(funcIds != null){
				for(int funId: funcIds){
					//给角色添加权限
					Function fun = fjdao.findByFunId(funId);
					role.getFunctions().add(fun);
				}
			}
			rjdao.save(role);
		} catch (Exception e) {
			e.printStackTrace();
			
		}
	}
	
	
	
	/**
	 * 给指定的角色绑定用户
	 * @param roleId
	 * @param funcIds
	 */
	public void grantUser(List userIds, int roleId){
		//获取所有角色
		List<User> userList=(List<User>) ujdao.findAll();
		Role role=rjdao.findByRoleId(roleId);
		for(User user:userList) {
			if(user.getRoles() == null){
				user.setRoles(new ArrayList());
			}
			user.getRoles().remove(role);
		}
		if(userIds!=null && userIds.size()>0) {
			for(Iterator it=userIds.iterator();it.hasNext();) {
				int userId=(int) it.next();
				User user=ujdao.findByUserId(userId);
				user.getRoles().add(role);
				ujdao.save(user);
			}
		}
	}
	
	/**
	 * 登陆
	 * @param name
	 * @param pass
	 * @return
	 */
	public User login(int userId, String psw){
		User user = ujdao.findByUserIdAndPassword(userId, psw);
		//用户校验完毕后
		if(user != null){
			//判断用户是否有登陆权限
			Set<Integer> set = getFunIdsByUserId(user.getUserId());
			if(set.contains(LOGIN_ID)){
				//当前用户存在ID为1 代表有登录权限
				return user;
			}
		}
		return null;
	}
	
	
	/**
	 *    根据用户ID找到该用户所有的功能ID
	 *    1：通过userId 获取用户信息
	 *    2：通过User 获取用户的角色列表
	 *    3：遍历角色列表，获取每个角色包含的权限列表
	 *    4：用Set集合存储权限列表 得到该用户的所有权限
	 *    5:  返回权限列表ID集合
	 * @param userId
	 * @return
	 */
	public Set<Integer> getFunIdsByUserId(int userId){
		//用set集合接收权限
		Set<Integer> funIds = new HashSet<Integer>();
		User user = ujdao.findByUserId(userId);
		List<Role> roleList = user.getRoles();
		if(roleList != null){
			for(Role role: roleList){
				List<Function> funList = role.getFunctions();
				if(funList != null){
					for(Function fun: funList){
						funIds.add(fun.getFunId());
					}
				}
			}
		}
		return funIds;
	}
}
